﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using T.FAS.Runtime.MF.Activities.Helper;
using T.FAS.Runtime.MF.Dao;
using T.FAS.Runtime.MF.Entity;

namespace T.FAS.Runtime.MF.Activities.Services
{
    public class QwenMaxRequestService : ILLMModelRequestService
    {
        public async Task<LLMResult> Request(RequestParam filter)
        {
            var dao = new LLMModelLogic();
            var llmModel = dao.GetLLMModels().Find(t => t.Name.ToLower() == filter.ModelName.ToLower());
            if (llmModel == null) return new LLMResult();

            var apiUrl = llmModel.Url;

            var jsonContent = new QWenMaxContent
            {
                // Model = llmModel.Name,
                Model = "qwen-max",
                Messages = filter.Prompts.Select(t => new QWenMessage { Role = t.Key.Split("/").Length > 1 ? t.Key.Split("/")[1] : t.Key.Split("/")[0], Content = t.Value.ToString() }).ToList(),
                Stream = false
            };
            if (filter.Options.ContainsKey("response_format"))
            {
                jsonContent.ResponseFormat = new ResponseFormat { Type = filter.Options["response_format"].ToString() };
            }
            if (filter.Options.ContainsKey("temperature"))
            {
                jsonContent.Temperature = Convert.ToInt32(filter.Options["temperature"]);
            }
            if (filter.Options.ContainsKey("top_p"))
            {
                jsonContent.TopP = Convert.ToInt32(filter.Options["top_p"]);
            }
            if (filter.Options.ContainsKey("top_k"))
            {
                jsonContent.TopK = Convert.ToInt32(filter.Options["top_k"]);
            }
            if (filter.Options.ContainsKey("top_k"))
            {
                jsonContent.TopK = Convert.ToInt32(filter.Options["top_k"]);
            }
            if (filter.Options.ContainsKey("repetition_penalty"))
            {
                jsonContent.RepetitionPenalty = Convert.ToDouble(filter.Options["repetition_penalty"]);
            }
            if (filter.Options.ContainsKey("max_tokens"))
            {
                jsonContent.MaxTokens = Convert.ToInt32(filter.Options["max_tokens"]);
            }
            var responseJson = await HttpHelper.SendPostRequestAsync(apiUrl, JsonConvert.SerializeObject(jsonContent), llmModel.ApiKey);
            var response = JsonConvert.DeserializeObject<Response>(responseJson);
            return new LLMResult { Response = string.Join(",", response.Choices.Select(t => t.Message.Content)), TokenUsage = response.Usage };
        }
    }
    internal class QWenMaxContent
    {
        [JsonProperty("model")]
        public string Model { get; set; }
        [JsonProperty("messages")]
        public List<QWenMessage> Messages { get; set; }

        [JsonProperty("stream")]
        public bool Stream { get; set; } = true;

        [JsonProperty("response_format")]
        public ResponseFormat ResponseFormat { get; set; }

        [JsonProperty("temperature", NullValueHandling = NullValueHandling.Ignore)]
        public int? Temperature { get; set; }

        [JsonProperty("top_p", NullValueHandling = NullValueHandling.Ignore)]
        public int? TopP { get; set; }
        [JsonProperty("top_k", NullValueHandling = NullValueHandling.Ignore)]
        public int? TopK { get; set; }
        [JsonProperty("repetition_penalty", NullValueHandling = NullValueHandling.Ignore)]
        public double? RepetitionPenalty { get; set; } = 1.0;
        [JsonProperty("max_tokens", NullValueHandling = NullValueHandling.Ignore)]
        public long? MaxTokens { get; set; }
    }

    internal class QWenMessage
    {
        [JsonProperty("role")]
        public string Role { get; set; }
        [JsonProperty("content")]
        public string Content { get; set; }
    }
    internal class ResponseFormat
    {
        [JsonProperty("type")]
        public string Type { get; set; }

    }

    internal class Response
    {
        [JsonProperty("created")]
        public int Created { get; set; }
        [JsonProperty("id")]
        public string ID { get; set; }
        [JsonProperty("model")]
        public string Model { get; set; }

        [JsonProperty("system_fingerprint")]
        public string SystemFingerprint { get; set; }

        [JsonProperty("usage")]
        public TokenUsage Usage { get; set; }

        [JsonProperty("choices")]
        public List<Choice> Choices { get; set; }
    }
    public class TokenUsage
    {
        [JsonProperty("completion_tokens")]
        public int CompletionTokens { get; set; }
        [JsonProperty("prompt_tokens")]
        public int PromptTokens { get; set; }
        [JsonProperty("total_tokens")]
        public int TotalTokens { get; set; }
    }
   internal class Choice
    {
        [JsonProperty("finish_reason")]
        public string FinishReason { get; set; }
        [JsonProperty("index")]
        public int Index { get; set; }
        [JsonProperty("logprobs")]
        public object Logprobs { get; set; }
        [JsonProperty("message")]
        public Message Message { get; set; }
    }
    internal class Message
    {
        [JsonProperty("content")]
        public string Content { get; set; }
        [JsonProperty("role")]
        public string Role { get; set; }
    }
}
